package com.micro.core.frame.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.micro.common.MicroResponseCode;
import com.micro.common.util.JacksonUtil;
import com.micro.common.util.ObjectUtil;
import com.micro.core.frame.mapper.BasicsMapper;
import com.micro.core.frame.service.BasicsService;
import com.micro.core.frame.util.EntityUtil;
import com.micro.core.page.PageQuery;
import com.micro.core.resp.RespJson;
import com.micro.core.resp.RespJsonData;
import com.micro.core.resp.RespJsonPageData;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

/**
 * @author LevelCoder
 * @version V1.0.0
 * @email LevelCoder@126.com
 * @date 2020/4/28
 */
public abstract class AbstractBasicsServiceImpl<T,PKType extends Serializable> implements BasicsService<T, PKType> {

    @Autowired
    private BasicsMapper<T> mapper;

    /**
     * <h2>根据对象查询对象:单条数据</h2>
     * @param entity    查询对象
     * @return
     */
    @Override
    public RespJsonData<T> selectOne(T entity) {
        T t = mapper.selectOne(entity);
        return new RespJsonData<T>(t, MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>根据主键编号查询对象</h2>
     * @param id   主键编号
     * @return
     */
    @Override
    public RespJsonData<T> findDetail(PKType id) {
        T t = mapper.selectByPrimaryKey(id);
        return new RespJsonData<T>(t, MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>通过Id查询,返回指定对象</h2>
     * @param id           主键编号
     * @param aClass       需要返回的对象
     * @return
     */
    @Override
    public RespJsonData findDetail(PKType id, Class<?> aClass) {
        T t = mapper.selectByPrimaryKey(id);
        Object object = JacksonUtil.getObject(JacksonUtil.toJson(t), aClass);
        return new RespJsonData(object, MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>根据对象查询列表 不带分页</h2>
     * @param entity   请求对象
     * @return
     */
    @Override
    public RespJsonData<List<T>> selectList(T entity) {
        List<T> ts = mapper.select(entity);
        return new RespJsonData<List<T>>(ts, MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>按条件查询列表 不带分页</h2>
     * @param map     请求参数
     * @return
     */
    @Override
    public RespJsonData<List<T>> findListAll(Map<String, Object> map) {
        Example example = createExample(map);
        List<T> list = mapper.selectByExample(example);
        return new RespJsonData<List<T>>(list, MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>按条件查询列表 不带分页,返回指定类型列表</h2>
     * @param map         请求参数
     * @param aClass      需要返回的对象
     * @return
     */
    @Override
    public RespJsonData findListAll(Map<String, Object> map, Class<?> aClass) {
        Example example = createExample(map);
        List<T> list = mapper.selectByExample(example);
        List<?> listDTO = JacksonUtil.getList(JacksonUtil.toJson(list), aClass);
        return new RespJsonData(listDTO, MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>查询列表 带分页</h2>
     * @param map    请求参数
     * @return
     */
    @Override
    public RespJsonPageData<T> findList(Map<String, Object> map) {
        PageQuery query = new PageQuery(map);
        Example example = createExample(map);
        Page<Object> result = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<T> list = mapper.selectByExample(example);
        return new RespJsonPageData<T>(list,result.getTotal(), MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>查询列表 带分页,返回指定类型列表</h2>
     * @param map           请求参数
     * @param aClass        需要返回的对象
     * @return
     */
    @Override
    public RespJsonPageData findList(Map<String, Object> map, Class<?> aClass) {
        PageQuery query = new PageQuery(map);
        Example example = createExample(map);
        Page<Object> result = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<T> list = mapper.selectByExample(example);
        List<?> listDTO = JacksonUtil.getList(JacksonUtil.toJson(list), aClass);
        return new RespJsonPageData(listDTO,result.getTotal(), MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>新增对象:直接做成选择行插入</h2>
     * @param entity
     * @return
     */
    @Override
    public RespJson addEntity(T entity) {
        EntityUtil.assignment(entity,true);
        mapper.insertSelective(entity);
        return new RespJson(MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>修改对象</h2>
     * @param entity
     * @return
     */
    @Override
    public RespJson editEntity(T entity) {
        EntityUtil.assignment(entity,false);
        mapper.updateByPrimaryKeySelective(entity);
        return new RespJson(MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>删除对象</h2>
     * @param entity   请求对象
     * @return
     */
    @Override
    public RespJson deleteEntity(T entity) {
        mapper.delete(entity);
        return new RespJson(MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());

    }

    /**
     * <h2>根据主键id删除对象</h2>
     * @param id      主键编号
     * @return
     */
    @Override
    public RespJson deleteById(PKType id) {
        mapper.deleteByPrimaryKey(id);
        return new RespJson(MicroResponseCode.SUCCESS.getResponseCode(), MicroResponseCode.SUCCESS.getResponseMessage());
    }

    /**
     * <h2>获取 Example 组合条件对象</h2>
     * @param map     请求参数
     * @return
     */
    @Override
    public Example getExample(Map<String, Object> map) {
        return createExample(map);
    }


    /**
     * 生成 Example 组合条件对象
     * @param query
     * @return
     */
    public Example createExample(Map<String, Object> query){
        removeQueryParams(query);
        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Example example = new Example(clazz);
        if(query.entrySet().size()>0) {
            Example.Criteria criteria = example.createCriteria();
            for (Map.Entry<String, Object> entry : query.entrySet()) {
                criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%");
            }
        }
        return example;
    }

    /**
     * <h2>移除分页查询参数</h2>
     * @param query
     */
    private void removeQueryParams(Map<String, Object> query) {
        if(ObjectUtil.isNotEmpty(query.get("pageNum"))){
            query.remove("pageNum");
        }
        if(ObjectUtil.isNotEmpty(query.get("pageSize"))){
            query.remove("pageSize");
        }
    }
}
